package per.chenxin.tools.foundation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Types;
import java.text.SimpleDateFormat;

public class OracleStringConverter implements StringConvertable {

    public static StringConvertable oracleStringConverter;

    public static final String STR_DATA_FORMAT = "yyyy/MM/dd HH:mm:ss";

    public static final String STR_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss.SSS";

    public static final String STR_TIMESTAMP_FORMAT = "yyyy/MM/dd HH:mm:ss.SSS";

    public static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat(STR_DATA_FORMAT);

    public static final SimpleDateFormat SIMPLE_TIME_FORMAT = new SimpleDateFormat(STR_TIME_FORMAT);

    public static final SimpleDateFormat SIMPLE_TIMESTAMP_FORMAT = new SimpleDateFormat(
        STR_TIMESTAMP_FORMAT);

    public static final String STR_DATA_FORMAT_DB = "YYYY/MM/DD HH24:MI:SS";

    public static final String STR_TIME_FORMAT_DB = "YYYY/MM/DD HH24:MI:SS.FF3";

    public static final String STR_TIMESTAMP_FORMAT_DB = "YYYY/MM/DD HH24:MI:SS.FF3";

    public static final String STR_DATA_METHOD_FORMAT_DB = "to_date";

    public static final String STR_TIME_METHOD_FORMAT_DB = "to_timestamp";

    public static final String STR_TIMESTAMP_METHOD_FORMAT_DB = "to_timestamp";

    public static final String STR_ROWID_CLASS = "oracle.sql.ROWID";

    public static final String STR_ROWID_TOSTRING = "stringValue";

    @Override
    public String toDbString(String str, int types) {

        StringBuffer sb = new StringBuffer();

        switch (types) {
            case Types.DATE:
                sb.append(STR_DATA_METHOD_FORMAT_DB);
                sb.append("('");
                sb.append(str);
                sb.append("', '");
                sb.append(STR_DATA_FORMAT_DB);
                sb.append("')");
                break;

            case Types.TIME:
                sb.append(STR_TIME_METHOD_FORMAT_DB);
                sb.append("('");
                sb.append(str);
                sb.append("', '");
                sb.append(STR_TIME_FORMAT_DB);
                sb.append("')");
                break;

            case Types.TIMESTAMP:
                sb.append(STR_TIMESTAMP_METHOD_FORMAT_DB);
                sb.append("('");
                sb.append(str);
                sb.append("', '");
                sb.append(STR_TIMESTAMP_FORMAT_DB);
                sb.append("')");
                break;

            case Types.CHAR:
                //FALL THROUGH
            case Types.VARCHAR:
                sb.append("'");
                sb.append(str);
                sb.append("'");

                break;

            default:
                if (str == null || str.length() == 0)
                    sb.append("''");
                else
                    sb.append(str);

        }

        return sb.toString();
    }

    @Override
    public String toJavaString(Object obj, int types) {

        try {
            return toJavaString(obj, types, null);
        } catch (ClassNotFoundException e) {
        } catch (SecurityException e) {
        } catch (IllegalArgumentException e) {
        } catch (NoSuchMethodException e) {
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        }
        return null;
    }

    @Override
    public String toJavaString(Object obj, int types, String columnClassName)
        throws ClassNotFoundException, SecurityException, NoSuchMethodException,
        IllegalArgumentException, IllegalAccessException, InvocationTargetException {

        if (obj == null)
            return null;

        switch (types) {
            case Types.ROWID:
                Method method = obj.getClass().getMethod(STR_ROWID_TOSTRING, new Class[] {});
                return (String) method.invoke(obj, new Object[] {});

            case Types.DATE:
                return SIMPLE_DATE_FORMAT.format(obj);

            case Types.TIME:
                return SIMPLE_TIME_FORMAT.format(obj);

            case Types.TIMESTAMP:

                return SIMPLE_TIMESTAMP_FORMAT.format(obj);

            case Types.CHAR:

                //FALL THROUGH

            case Types.VARCHAR:

                //FALL THROUGH

            default:
                if (columnClassName == null)
                    return obj.toString();
                return Class.forName(columnClassName, true, Util.getURLClassLoader()).cast(obj).toString();

        }
    }

    private OracleStringConverter() {

    }

    public static StringConvertable getInstance() {

        if (oracleStringConverter == null)
            oracleStringConverter = new OracleStringConverter();
        return oracleStringConverter;
    }

}
